package com.kungfu.controller;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.kungfu.config.Constant;
import com.kungfu.entity.DataInsertResult;
import com.kungfu.entity.GfjsZzd;
import com.kungfu.entity.OutpatientResponse;
import com.kungfu.entity.request.*;
import com.kungfu.entity.response.*;
import com.kungfu.service.ZzdService;
import com.kungfu.utils.DateUtils;
import com.kungfu.utils.HttpUtils;
import com.kungfu.utils.ResultCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;

@RestController
public class ZzdController extends BaseController {
    @Autowired
    private ZzdService zzdService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private HttpUtils httpUtils;

    @Autowired
    private DateUtils dateUtils;

    @PostMapping("/queryZzdIsExist")
    public String queryZzdIsExist(@RequestBody String data) {
        //1、门诊、住院，首次登记都会调用该接口，返回转诊单号给协和
        //2、华科his开出的转诊单类型默认都是门诊type=2，类型需要根据协和传入改接口的参数，来修改转诊单类型。
        //3、目前允许门诊转住院，不允许住院转门诊
        String methodName = "queryZzdIsExist";
        printDebug(methodName, data);
        MakeSureUserRequest sureUserRequest = null;
        MakeSureUserResponse response = new MakeSureUserResponse();
        try {
            sureUserRequest = new Gson().fromJson(data, MakeSureUserRequest.class);

            if (StringUtils.isEmpty(sureUserRequest.getJZRQ()) || StringUtils.isEmpty(sureUserRequest.getSFZH()) ||
                    StringUtils.isEmpty(sureUserRequest.getYYBH()) || StringUtils.isEmpty(sureUserRequest.getZZDLX())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            int zzd_type = Integer.valueOf(sureUserRequest.getZZDLX());

            if (zzd_type == Constant.ZzdType.ZY) {
                // start 20181031 by chj
                //判断是否存在已生效的住院，住院不可以转门诊
                GfjsZzd tmp1Zzd = zzdService.queryZzdIsVaild(sureUserRequest.getSFZH());
                if(null != tmp1Zzd){
                    response.setResult(ResultCodeEnum.ZZD_IS_EXIST);
                    printDebug(methodName,response.toString());
                    return response.toString();
                }
                // end 20181031 by chj

                //start 20190108 by chj
                //如果是学生，门诊不允许转住院
                GfjsZzd gfjsZzd = zzdService.queryZzdByCardNo(sureUserRequest.getSFZH());
                if(null != gfjsZzd && gfjsZzd.getUserType() == Constant.UserType.STUDEND){
                    response.setResult(ResultCodeEnum.NO_ALLOW_ZM_TO_ZY_ST);
                    return response.toString();
                }
                //end 20190108 by chj

                //住院业务--通过身份证号，修改转诊单状态为住院
                response = zzdService.queryZzdByUserInfo(sureUserRequest);
                //住院转诊单不存在 查询否有生效门诊
                if (response == null) {
                    //先查询是否存在生效的 门诊转诊单 判断是否为门诊转住院
                    GfjsZzd zzdh = zzdService.queryUsedMzZzd(sureUserRequest);

                    //复制 更改转诊单号
                    if (zzdh != null) {
                        if ( zzdh.getUserType() == Constant.UserType.STUDEND) {
                            response.setResult(ResultCodeEnum.USER_TYPE_ERROR);
                            printDebug(methodName, response.toString());
                            return response.toString();
                        }
                        //修改状态
                        int updateResult = zzdService.cancelZzd(zzdh.getZzdNo());
                        //复制新的zzd
                        if (updateResult > 0) {
                            zzdService.createNewZzd(zzdh);
                        }
                        response = zzdService.queryZzdByUserInfo(sureUserRequest);
                    }
                }

            } else if (zzd_type == Constant.ZzdType.MZ) {
                //门诊业务

                //先查询生效的门诊转诊单
                response = zzdService.queryMXzZdBySate(sureUserRequest);
                if (response == null) {
                    response = zzdService.queryMzZzdByUserInfo(sureUserRequest);
                    //生效转诊单
                    if (response != null) {
                        zzdService.updateZZdState(response.getZZDH());
                    }
                }
            }
            if (response != null) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                //未检出未生效zzd 查询是否有生效zzd
                response = new MakeSureUserResponse();
                List<String> list = zzdService.queryUsedZzd(sureUserRequest.getSFZH());
                if (list.isEmpty()) {
                    response.setResult(ResultCodeEnum.ACCOUNT_NOT_EXIST);
                } else {
                    response.setResult(ResultCodeEnum.ZZD_IS_EXIST);
                }
            }

        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    @PostMapping("/cancelRegistration")
    public String cancelRegistration(@RequestBody String data) {
        String methodName = "cancelRegistration";
        printDebug(methodName, data);
        BaseResponse response = new BaseResponse();
        CancelRegistrationRequest request = null;
        try {
            request = new Gson().fromJson(data, CancelRegistrationRequest.class);
            if (StringUtils.isEmpty(request.getSFZH()) || StringUtils.isEmpty(request.getJZBH())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            int result = zzdService.cancelRegistration(request);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.FAIL);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }


    @PostMapping("/inpatientRegistration")
    public String inpatientRegistration(@RequestBody String data) {
        String methodName = "inpatientRegistration";
        InpatientResponse response = new InpatientResponse();
        printDebug(methodName, data);
        InpatientRequest request = null;
        try {
            request = new Gson().fromJson(data, InpatientRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }

            if (StringUtils.isEmpty(request.getSFZH()) ||
                    StringUtils.isEmpty(request.getYHXM()) ||
                    StringUtils.isEmpty(request.getJZBH()) ||
                    StringUtils.isEmpty(request.getZZDH()) ||
                    StringUtils.isEmpty(request.getZYHM()) ||
                    StringUtils.isEmpty(request.getZYKS()) ||
                    StringUtils.isEmpty(request.getZYKSBM()) ||
                    StringUtils.isEmpty(request.getRYRQ()) ||
                    StringUtils.isEmpty(request.getJZKH())
                    ) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            int result = zzdService.inpatientHospital(request);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
                response.setJZJLH(request.getZZDH());
            } else {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);

        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    @PostMapping("/inpatientCharge")
    public String inpatientCharge(@RequestBody String data) {
        String methodName = "inpatientCharge";
        printDebug(methodName, data);
        InpatientChargeResponse response = new InpatientChargeResponse();
        InpatientChargeRequest request = null;
        try {
            request = new Gson().fromJson(data, InpatientChargeRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }
            if (StringUtils.isEmpty(request.getZYH()) ||
                    StringUtils.isEmpty(request.getZZDH()) ||
                    StringUtils.isEmpty(request.getHZID()) ||
                    StringUtils.isEmpty(request.getYYBM()) ||
                    StringUtils.isEmpty(request.getCYKS()) ||
                    StringUtils.isEmpty(request.getCYRQ()) ||
                    StringUtils.isEmpty(request.getZYTS()) ||
                    StringUtils.isEmpty(request.getDHNO())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            //start-20181025 by chj
            //結算時，判斷該患者是否已經住院，如果是住院，則不允許進行門診結算
            /*GfjsZzd gfjsZzd = zzdService.queryInfoByZYH(request.getZZDH());
            if(null != gfjsZzd && gfjsZzd.getZzdType().equals("1")){
                response.setResult(ResultCodeEnum.NOT_ALLOW_JS);
                printDebug(methodName,response.toString());
                return response.toString();
            }*/
            //end-20181025 by chj
            int updateInfoResult = zzdService.updateZzdInfo(request);
            if (updateInfoResult < 1) {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            CheckParams checkParams = new CheckParams();
            checkParams.setType(Constant.CHECK_TYPE.OUT_CHECK);
            checkParams.setZzdNo(request.getZZDH());
            checkParams.setRedoFlag("0");
            CheckResponse checkResponse = httpUtils.getCheckData(restTemplate, checkParams);
            printDebug(methodName, checkResponse.toString());
            if (checkResponse.getStatus() == 0) {
                response.setFZJE((checkResponse.getData().getTotalFee() / 100d) + "");
                response.setGFZJE((checkResponse.getData().getGfFee() / 100d) + "");
                response.setZFZJE((checkResponse.getData().getZfFee() / 100d) + "");
                response.setJSXH(checkResponse.getData().getCheckoutNo());
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.OTHER_ERROR);
            }

        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    @PostMapping("/cancelCharge")
    public String cancelCharge(@RequestBody String data) {
        CancelChargeResponse response = new CancelChargeResponse();
        String methodName = "cancelCharge";
        printDebug(methodName, data);
        CancelChargeRequest request = null;
        try {
            request = new Gson().fromJson(data, CancelChargeRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }
            if (StringUtils.isEmpty(request.getJZJLH()) ||
                    StringUtils.isEmpty(request.getJSXH()) ||
                    StringUtils.isEmpty(request.getJBR())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            int result = zzdService.cancelCharge(request);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    /**
     * 住院结算
     * @param data
     * @return
     */
    @PostMapping("/ready2Charge")
    public String ready2Charge(@RequestBody String data) {
        InpatientChargeResponse response = new InpatientChargeResponse();
        String methodName = "ready2Charge";
        printDebug(methodName, data);
        ReadyToChargeRequest request = null;
        try {
            request = new Gson().fromJson(data, ReadyToChargeRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }
            if (StringUtils.isEmpty(request.getJZJLH()) ||
                    StringUtils.isEmpty(request.getZYH()) ||
                    StringUtils.isEmpty(request.getZZDH()) ||
                    StringUtils.isEmpty(request.getHZXM()) ||
                    StringUtils.isEmpty(request.getHZID()) ||
                    StringUtils.isEmpty(request.getJZKH()) ||
                    StringUtils.isEmpty(request.getYYBM()) ||
                    StringUtils.isEmpty(request.getSJDFEE()) ||
                    StringUtils.isEmpty(request.getSJDNUM()) ||
                    StringUtils.isEmpty(request.getJZLB())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            DataInsertResult insertResult = zzdService.readyToCharge(request);
            switch (insertResult.getResultCode()) {
                case Constant.CHECK_DATA_RESULT.CHECK_NOT_OK:
                    response.setResult(ResultCodeEnum.CHECK_NOT_OK);
                    printDebug(methodName, response.toString());
                    return response.toString();
                case Constant.CHECK_DATA_RESULT.DATA_NOT_EXIST:
                    response.setResult(ResultCodeEnum.DATA_NOT_EXIST);
                    response.setNotExistData(zzdService.queryUserUnExistData(request.getHZID()));
                    printDebug(methodName, response.toString());
                    return response.toString();
            }

            if (insertResult.getResultCode() >= 0) {
                CheckParams checkParams = new CheckParams();
                checkParams.setType(Constant.CHECK_TYPE.DISPLAY_CHECK);
                checkParams.setZzdNo(request.getZZDH());
                checkParams.setRedoFlag("1");
                CheckResponse checkResponse = httpUtils.getCheckData(restTemplate, checkParams);
                printDebug(methodName, checkResponse.toString());
                if (checkResponse.getStatus() == 0) {
                    response.setFZJE((checkResponse.getData().getTotalFee() / 100d) + "");
                    response.setGFZJE((checkResponse.getData().getGfFee() / 100d) + "");
                    response.setZFZJE((checkResponse.getData().getZfFee() / 100d) + "");
                    response.setResult(ResultCodeEnum.SUCCESS);
                } else {
                    response.setResult(ResultCodeEnum.OTHER_ERROR);
                }
            } else {
                response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            }

        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    /**
     * 离院小结
     *
     * @return
     */
    @PostMapping("/outHospitalSave")
    public String outHospitalSave(@RequestBody String data) {
        BaseResponse response = new BaseResponse();
        String methodName = "outHospitalSave";
        printDebug(methodName, data);
        OutHospitalRequest request = null;
        try {
            request = new Gson().fromJson(data, OutHospitalRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }

            if (StringUtils.isEmpty(request.getJZJLH())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);

        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    /**
     * 日结算查询
     *
     * @return
     */
    @PostMapping("/inpatientDailyQuery")
    public String inpatientDailyQuery(@RequestBody String data) {
        String methodName = "inpatientDailyQuery";
        printDebug(methodName, data);
        DailyQueryResponse response = new DailyQueryResponse();
        DailyQueryRequest request = null;
        try {
            request = new Gson().fromJson(data, DailyQueryRequest.class);
//            if (!request.check()){
//                response.setResult(ResultCodeEnum.ACCOUNT_NULL);
//                return response.toString();
//            }

            if (StringUtils.isEmpty(request.getJZJLH()) ||
                    StringUtils.isEmpty(request.getZZDH()) ||
                    StringUtils.isEmpty(request.getSFZH()) ||
                    StringUtils.isEmpty(request.getHZXM()) ||
                    StringUtils.isEmpty(request.getJSRQ()) ||
                    StringUtils.isEmpty(request.getJSQSRQ()) ||
                    StringUtils.isEmpty(request.getJSZZRQ()) ||
                    StringUtils.isEmpty(request.getJSTS())
                    ) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            response = zzdService.dailyChargeQuery(request);
            if (response != null) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    /**
     * 门诊结算
     * @param data
     * @return
     */
    @PostMapping("/outpatientCharge")
    public String outpatientCharge(@RequestBody String data) {
        String methodName = "outpatientCharge";
        printDebug(methodName, data);
        OutpatientResponse response = new OutpatientResponse();
        OutpatientRequest request = null;
        try {
            request = new Gson().fromJson(data, OutpatientRequest.class);
            if (StringUtils.isEmpty(request.getYYBH()) ||
                    StringUtils.isEmpty(request.getJZBH()) ||
                    StringUtils.isEmpty(request.getHZXM()) ||
                    StringUtils.isEmpty(request.getHZID()) ||
                    StringUtils.isEmpty(request.getJZKH()) ||
                    StringUtils.isEmpty(request.getZZDH()) ||
                    StringUtils.isEmpty(request.getJZRQ()) ||
                    StringUtils.isEmpty(request.getJZKS()) ||
                    StringUtils.isEmpty(request.getFPHM()) ||
                    StringUtils.isEmpty(request.getJSRQ())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            //start 20181101 by chj
            //如果患者已经存在已生效的住院，则不允许进行门诊结算。
            GfjsZzd gfjsZzd = zzdService.queryZyExist(request.getZZDH());
            if(null != gfjsZzd){
                response.setResult(ResultCodeEnum.NO_ALLOW_ZY_TO_ZM);
                printDebug(methodName,response.toString());
                return response.toString();
            }
            //end 20181101 by chj
            DataInsertResult result = zzdService.outpatientCharge(request);
            switch (result.getResultCode()) {
                case Constant.CHECK_DATA_RESULT.CHECK_NOT_OK:
                    response.setResult(ResultCodeEnum.CHECK_NOT_OK);
                    printDebug(methodName, response.toString());
                    return response.toString();
                case Constant.CHECK_DATA_RESULT.DATA_NOT_EXIST:
                    response.setResult(ResultCodeEnum.DATA_NOT_EXIST);
                    response.setNotExistData(zzdService.queryUserUnExistData(request.getHZID()));
                    printDebug(methodName, response.toString());
                    return response.toString();
            }
            if (result.getResultCode() >= 0) {
                CheckParams checkParams = new CheckParams();
                checkParams.setType(Constant.CHECK_TYPE.MZ_CHECK);
                checkParams.setZzdNo(request.getZZDH());
                checkParams.setRedoFlag("1");
                checkParams.setSjdh(request.getFPHM());
                CheckResponse checkResponse = httpUtils.getCheckData(restTemplate, checkParams);
                printDebug(methodName, checkResponse.toString());
                if (checkResponse.getStatus() == 0) {
                    response.setZJJE((checkResponse.getData().getTotalFee() / 100d) + "");
                    response.setGFZE((checkResponse.getData().getGfFee() / 100d) + "");
                    response.setZFZE((checkResponse.getData().getZfFee() / 100d) + "");
                    response.setJSSJ(dateUtils.parseDate2Sjdh(new Date()));
                    response.setJSXH(checkResponse.getData().getCheckoutNo());
                    response.setResult(ResultCodeEnum.SUCCESS);
                } else {
                    response.setResult(ResultCodeEnum.OTHER_ERROR);
                }
            } else {
                response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            }

        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }

    @PostMapping("/cancelOutPatientCharge")
    public String cancelOutPatientCharge(@RequestBody String data) {
        BaseResponse response = new BaseResponse();
        String methodName = "cancelOutPatientCharge";
        printDebug(methodName, data);
        CancelOutPatientChargeRequest request = null;
        try {
            request = new Gson().fromJson(data, CancelOutPatientChargeRequest.class);
            if (StringUtils.isEmpty(request.getZZDH()) || StringUtils.isEmpty(request.getFPHM())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return response.toString();
            }
            //查询转诊单状态
            String status = zzdService.getZzdStatus(request.getZZDH());
            if ("1".equals(status)) {
                int result = zzdService.cancelOutpatientCharge(request);
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.ZZD_STATUS_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return response.toString();
    }
}
